package com.wande.dataplatform.filecollection.validation.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wande.dataplatform.filecollection.domain.dto.ValidationError;
import com.wande.dataplatform.filecollection.validation.IValidationRule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 唯一性校验规则
 * 校验字段值在当前批次数据中是否唯一
 * 配置格式: {"scope": "BATCH|GLOBAL", "message": "错误消息"}
 * 
 * 注意：此规则需要在批量校验时使用，单条记录校验无法判断唯一性
 *
 * @author wande
 */
@Slf4j
@Component
public class UniqueValidationRule implements IValidationRule {

    /**
     * 存储已出现的值，用于批量校验
     * key: fieldName, value: 已出现的值集合
     */
    private final ConcurrentHashMap<String, Set<String>> valueCache = new ConcurrentHashMap<>();

    @Override
    public String getRuleType() {
        return "UNIQUE";
    }

    @Override
    public ValidationError validate(String fieldName, Object value, String ruleConfig) {
        // 如果值为空，跳过校验
        if (value == null) {
            return null;
        }

        try {
            JSONObject config = JSONUtil.parseObj(ruleConfig);
            String scope = config.getStr("scope", "BATCH");
            String message = config.getStr("message", "值重复");

            String valueStr = value.toString();

            // 获取或创建该字段的值集合
            Set<String> values = valueCache.computeIfAbsent(fieldName, k -> new HashSet<>());

            // 检查值是否已存在
            if (values.contains(valueStr)) {
                return new ValidationError(
                    fieldName,
                    getRuleType(),
                    String.format("字段 [%s] 的值 %s %s", fieldName, valueStr, message),
                    value,
                    null
                );
            }

            // 添加到已出现的值集合
            values.add(valueStr);

            return null;
        } catch (Exception e) {
            log.error("唯一性校验规则执行失败: {}", e.getMessage());
            return new ValidationError(
                fieldName,
                getRuleType(),
                String.format("字段 [%s] 唯一性校验失败: %s", fieldName, e.getMessage()),
                value,
                null
            );
        }
    }

    @Override
    public boolean isValidConfig(String ruleConfig) {
        try {
            JSONObject config = JSONUtil.parseObj(ruleConfig);
            String scope = config.getStr("scope", "BATCH");
            
            // 验证scope值
            return "BATCH".equals(scope) || "GLOBAL".equals(scope);
        } catch (Exception e) {
            log.error("唯一性校验规则配置无效: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 清除缓存
     * 在批量校验完成后调用
     */
    public void clearCache() {
        valueCache.clear();
    }

    /**
     * 清除指定字段的缓存
     */
    public void clearCache(String fieldName) {
        valueCache.remove(fieldName);
    }
}
